package eu.jba.denshijisho.util;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.lang.reflect.Array;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
import android.os.Environment;
import android.view.Surface;
import android.view.WindowManager;
import android.widget.Toast;
import eu.jba.denshijisho.R;

@SuppressLint("SimpleDateFormat")
public class Util {
	public static String readRawFile(Context context, int resourceId) {
		final InputStream is = context.getResources().openRawResource(
				resourceId);
		final BufferedReader r = new BufferedReader(new InputStreamReader(is));
		final StringBuilder total = new StringBuilder();
		String line;
		try {
			while ((line = r.readLine()) != null) {
				total.append(line);
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
		return total.toString();
	}

	public static void getUnsupportedOperation(Context context){
		final Toast toast = Toast.makeText(
			context, R.string.unimplemented_operation, Toast.LENGTH_LONG);
		toast.show();
	}
	
	public static String dateToString(Date date){
		final SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
		return simpleDateFormat.format(date);
	}
	
	public static Date stringToDate(String date){
		final SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
		try{
			return simpleDateFormat.parse(date);
		}catch(ParseException e){
			e.printStackTrace();
		}
		return null; // something goes wrong
	}
	
	public static <T>  void exportDB(Context context, ExportHolder<T> exportHolder, String tableName){
		final File exportDir = new File( Environment.getExternalStorageDirectory(), "");
		if( !exportDir.exists() ){
			exportDir.mkdirs();
		}
		try{
			final File backupFile = new File( exportDir, tableName + ".csv");
			final Writer out = new BufferedWriter( 
				new OutputStreamWriter(
					new FileOutputStream( backupFile ), "UTF8"
				)
			);	

			out.append( arrayToString( exportHolder.getColumnNames(), "," ) ).append("\r\n");
			
			final Iterator<T> dataIterator = exportHolder.getDataToConvert().iterator();
			while( dataIterator.hasNext() ){
				T row = dataIterator.next();
				out.append( arrayToString( exportHolder.convertToStringData(row), "," ) ).append("\r\n");
			}
			out.flush();
			out.close();
			Toast.makeText(context, tableName + " exported", Toast.LENGTH_LONG).show();
		}catch(IOException e){
			e.printStackTrace();
		}
	}
	
	public static String arrayToString(String[] array, String separator){
		final StringBuilder sb = new StringBuilder();
        for( int i = 0; i < array.length; ++i ){
            if( i != 0 ){
                sb.append( separator );
            }
            sb.append( Array.get( array, i ) );			
		}
        return sb.toString();
	}
	
    public static Date convertToDate(long millis) {
        Calendar cal = Calendar.getInstance();
        cal.setTimeInMillis(millis);
        return cal.getTime();
    }
	
    public static Integer convertToMilliseconds(Integer days){
        return days * 24 * 60 * 60 * 1000;
    }

    public static Date addDate( Date date, int year, int month, int day ){
        final Calendar calendar = Calendar.getInstance();
        calendar.setTime( date );
        calendar.add( Calendar.YEAR, year );
        calendar.add( Calendar.MONTH, month );
        calendar.add( Calendar.DAY_OF_MONTH, day );
        
        return calendar.getTime();
    }

	
	public static abstract class ExportHolder<T>{
		private List<T> dataToConvert;
		
		public ExportHolder(List<T> data){
			this.dataToConvert = data;
		}
		
		public abstract String[] convertToStringData(T row);
		public abstract String[] getColumnNames();
		
		public List<T> getDataToConvert(){
			return dataToConvert;
		}
	}
	
	public static void lockScreenOrientation(Activity activity){
		final WindowManager windowManager = (WindowManager)activity.getSystemService(Context.WINDOW_SERVICE);
		final Configuration configuration = activity.getResources().getConfiguration();
		final int rotation = windowManager.getDefaultDisplay().getRotation();
		
		if( configuration.orientation == Configuration.ORIENTATION_LANDSCAPE 
			&& (rotation== Surface.ROTATION_0 || rotation == Surface.ROTATION_180) ||
			configuration.orientation == Configuration.ORIENTATION_PORTRAIT && 
			(rotation == Surface.ROTATION_90 || rotation == Surface.ROTATION_270 )){
			switch( rotation ){
			case Surface.ROTATION_0 :
				activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
				break;
			case Surface.ROTATION_90 :
				activity.setRequestedOrientation( ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT);
				break;
			case Surface.ROTATION_180 :
				activity.setRequestedOrientation( ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE);
				break;
			case Surface.ROTATION_270 :
				activity.setRequestedOrientation( ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
				break;
			}
		}else{
			switch( rotation ){
			case Surface.ROTATION_0 :
				activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
				break;
			case Surface.ROTATION_90 :
				activity.setRequestedOrientation( ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
				break;
			case Surface.ROTATION_180 :
				activity.setRequestedOrientation( ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT);
				break;
			case Surface.ROTATION_270 :
				activity.setRequestedOrientation( ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE);
				break;
			}
		}
	}
	
	public static void unlockScreenOrientation(Activity activity){
		activity.setRequestedOrientation( ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
	}
}
